package org.minuframework.aop;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.JoinPoint.StaticPart;
import org.aspectj.lang.Signature;
import org.aspectj.lang.reflect.SourceLocation;
import org.minuframework.lang.StringUtils;

public class JoinPointBuilder{
    
    private JoinPoint          joinPoint;
    private Signature          signature;
    private SourceLocation     sourceLocation;
    private StaticPart         staticPart;
    private HttpServletRequest httpServletRequest;
    private Object             target;
    private Object[]           args;
    private String             shortString;
    private String             longString;
    private String             kind;
    
    public JoinPointBuilder(JoinPoint joinPoint){
        this.joinPoint = joinPoint;
        this.signature = joinPoint.getSignature();
        this.sourceLocation = joinPoint.getSourceLocation();
        this.staticPart = joinPoint.getStaticPart();
        this.target = joinPoint.getTarget();
        this.args = joinPoint.getArgs();
        this.shortString = joinPoint.toShortString();
        this.longString = joinPoint.toLongString();
        this.kind = joinPoint.getKind();
    }
    
    public Object getThis(){
        return joinPoint.getThis();
    }
    
    public JoinPoint getJoinPoint(){
        return joinPoint;
    }
    
    public Signature getSignature(){
        if (signature == null) {
            this.signature = joinPoint.getSignature();
        }
        return signature;
    }
    
    public String getSignatureName(){
        return getSignature().getName();
    }
    
    public SourceLocation getSourceLocation(){
        if (sourceLocation == null) {
            this.sourceLocation = joinPoint.getSourceLocation();
        }
        return sourceLocation;
    }
    
    public StaticPart getStaticPart(){
        if (staticPart == null) {
            this.staticPart = joinPoint.getStaticPart();
        }
        return staticPart;
    }
    
    public Object getTarget(){
        if (target == null) {
            this.target = joinPoint.getTarget();
        }
        return target;
    }
    
    public String getTargetName(){
        return getTarget().getClass().getName();
    }
    
    public boolean isTarget(Class<? extends Object> classOff){
        return getTargetName().equals(classOff.getName());
    }
    
    public Object[] getArgs(){
        if (args == null) {
            this.args = joinPoint.getArgs();
        }
        return args;
    }
    
    public String getShortString(){
        if (StringUtils.isEmpty(shortString)) {
            this.shortString = joinPoint.toShortString();
        }
        return shortString;
    }
    
    public String getLongString(){
        if (StringUtils.isEmpty(longString)) {
            this.longString = joinPoint.toLongString();
        }
        return longString;
    }
    
    public String getKind(){
        if (StringUtils.isEmpty(kind)) {
            this.kind = joinPoint.getKind();
        }
        return kind;
    }
    
    public HttpServletRequest getHttpServletRequest(){
        if (httpServletRequest == null) {
            for (Object object : getArgs()) {
                if (object instanceof HttpServletRequest) {
                    this.httpServletRequest = (HttpServletRequest) object;
                    break;
                }
            }
        }
        return httpServletRequest;
    }
    
}
